# FluentQueries.java

    package org.codefilarete.stalactite.query.model;

    import java.util.Map;

    import org.codefilarete.stalactite.query.api.CriteriaChain;
    import org.codefilarete.stalactite.query.api.Fromable;
    import org.codefilarete.stalactite.query.api.Selectable;
    import org.codefilarete.stalactite.query.api.Selectable.SimpleSelectable;
    import org.codefilarete.stalactite.query.builder.WhereSQLBuilderFactory.WhereSQLBuilder;
    import org.codefilarete.stalactite.query.model.FluentQuery.FluentSelectClause;
    import org.codefilarete.stalactite.query.model.FluentQuery.SelectAwareAliasExpression;
    import org.codefilarete.stalactite.sql.ddl.structure.Column;

    /**
     * A utility class that offers static factory methods for query or criteria construction, eliminating the need for
     * "new Query()" code followed by method chaining.
     *
     * @author Guillaume Mary
     */
    public class FluentQueries {

    	public static FluentSelectClause select(Iterable<? extends Selectable<?>> selectables) {
    		return new FluentQuery().select(selectables);
    	}

    	public static <C> SelectAwareAliasExpression select(String expression, Class<C> javaType) {
    		return new FluentQuery().select(expression, javaType);
    	}

    	public static FluentSelectClause select(Selectable<?> expression, Selectable<?>... expressions) {
    		return new FluentQuery().select(expression, expressions);
    	}

    	public static FluentSelectClause select(Selectable<?> column) {
    		return new FluentQuery().select(column);
    	}

    	public static FluentSelectClause select(Selectable<?> column, String alias) {
    		return new FluentQuery().select(column, alias);
    	}

    	public static FluentSelectClause select(Selectable<?> col1, String alias1, Selectable<?> col2, String alias2) {
    		return new FluentQuery().select(col1, alias1, col2, alias2);
    	}

    	public static FluentSelectClause select(Selectable<?> col1, String alias1, Selectable<?> col2, String alias2, Selectable<?> col3, String alias3) {
    		return new FluentQuery().select(col1, alias1, col2, alias2, col3, alias3);
    	}

    	public static FluentSelectClause select(Map<? extends Selectable<?>, String> aliasedColumns) {
    		return new FluentQuery().select(aliasedColumns);
    	}

    	public static FluentQuery from(Fromable rootTable) {
    		FluentQuery fluentQuery = new FluentQuery();
    		fluentQuery.from(rootTable);
    		return fluentQuery;
    	}

    	public static CriteriaChain<?> where(Selectable<?> column, String condition) {
    		return new Where(column, condition);
    	}

    	public static <O> CriteriaChain<?> where(Selectable<O> column, ConditionalOperator<? super O, ?> condition) {
    		return new Where(column, condition);
    	}

    	public static CriteriaChain<?> where(Object... criteria) {
    		return new Where(criteria);
    	}

    	/**
    	 * Shortcut to create a {@link Criteria}.
    	 * Combined with {@link WhereSQLBuilder} it will add parenthesis around it.
    	 *
    	 * @param column a {@link Column}
    	 * @param condition the criteria on the {@link Column}
    	 * @return a new {@link Criteria}
    	 */
    	public static Criteria<?> filter(Selectable<?> column, String condition) {
    		return new Criteria<>(column, condition);
    	}

    	/**
    	 * Shortcut to create a {@link Criteria}.
    	 * Combined with {@link WhereSQLBuilder} it will add parenthesis around it.
    	 *
    	 * @param column a {@link Column}
    	 * @param condition the criteria on the {@link Column}
    	 * @return a new {@link Criteria}
    	 */
    	public static Criteria<?> filter(Selectable<?> column, ConditionalOperator condition) {
    		return new Criteria<>(column, condition);
    	}

    	/**
    	 * Shortcut to create a {@link Criteria}.
    	 * Combined with {@link WhereSQLBuilder} it will add parenthesis around it.
    	 *
    	 * @param columns a combination of objects describing the criteria
    	 * @return a new {@link Criteria}
    	 */
    	public static Criteria<?> filter(Object ... columns) {
    		return new Criteria<>(columns);
    	}

    	public static <C> Selectable<Object> column(String name) {
    		return new SimpleSelectable<>(name, Object.class);
    	}
    }